﻿using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.CounterManager;
using ApplicationLibrary.DBManager;
using ApplicationLibrary.ExtendedControls;
using ApplicationLibrary.SqlConnector;
using Clothes.Items.ModuleData;
using Clothes.Masters.ModuleData;
using Clothes.Sales.ModuleData;
using System;
using Clothes.Sales.Reports.DataSet;
using Clothes.Sales.Reports;

namespace Clothes.Sales.Forms
{
    public abstract partial class SaleDoc : ApplicationLibrary.DBManager.DocumentForm
    {
        protected const string BTN_LOAD = "BtnLoad";
        protected const string PRINT_INVOICE = "PRNT_INVOICE";
        protected const string PRINT_ENVELOPE = "PRINT_ENVELOPE";

        protected DRMasters drMasters;
        protected DUItem duItem;
        protected SalesType salesType;

        protected abstract bool LoadItemsInDocument();
        protected abstract void DoRowDeleted(DataRow drw);
        protected abstract void DoRowAdded(DataRow drw);
        protected abstract void LoadRow(SqlABDataReader dr);

        public int Customer
        {
            get { return rdrCustomer.CounterNumericValue; }
            set { rdrCustomer.CounterNumericValue = value; rdrCustomer_Validated(null, EventArgs.Empty); }
        }

        public DateTime DocDate
        {
            get { return ctbDate.Today; }
            set {  ctbDate.Today = value; }
        }

        public void AddNewRow(int itemid)
        {
            duItem.Find(itemid);
            DataRowView drw = dgwSaleDocDetail.AddNewRow();
            DataRowViewValues.SetValue<int>(drw, CL_SalesDetail.ItemID, itemid);
            DataRowViewValues.SetValue<string>(drw, CL_SalesDetail.Description, duItem.GetValue<string>(CL_Items.Description));
            DataRowViewValues.SetValue<double>(drw, CL_SalesDetail.Price, duItem.GetValue<double>(CL_Items.PriceSale));
        }

        public SaleDoc(SalesType salestype, string formName)
            : base(formName)
        {
            salesType = salestype;
            InitializeComponent();
            this.Text = formName;
            //AccountingPref = new PreferencesManager<AccountingPref>(this.Name, null).ReadPreference();
            //if (!AccountingPref.EnableTax)
            //    tabControl1.TabPages.RemoveByKey(tpgCastleTax.Name);
        }

        protected CounterControl FncInvoiceNo { get { return fncInvoiceNo; } }
        protected override void OnAttachData()
        {
            dbManager = new dbmanagerSale("SaleForm", new RadarSale(salesType), this) { SalesType = salesType };
            
            dbManager.AddMaster(this, CL_Sales.Name, true);
            dbManager.AddSlave(CL_SalesDetail.Name, true);
            dbManager.AddRelation("CL_SalesDetail", new iColumn[] { CL_Sales.SaledocType, CL_Sales.DocumentNo },
                                                        new iColumn[] { CL_SalesDetail.SaledocType, CL_SalesDetail.DocumentNo }, true);

            dbManager.AddColumn(CL_SalesDetail.Description);

            rdrCustomer.RadarForm = new Clothes.Masters.ModuleData.RadarMasters();
            rdrCustomer.AttachCounterType(Counters.Masters.Int(), GlobalInfo.CurrentDate, null);
            rdrCustomer.DescriptionControl = txtDescription;

            inv_Item.RadarForm = new Clothes.Items.ModuleData.RadarItems() { EnableAddOnFly = false, MustExistCode = true };
            inv_Item.AttachCodeType(Properties.Resources.CN_Items);

            duItem = new DUItem(true);
            drMasters = new DRMasters(false);
        }

        protected override bool OnBeforeDelete()
        {
            foreach (DataRow drw in dbManager.GetDataTable("CL_SalesDetail").Rows)
                DoRowDeleted(drw);

            return base.OnBeforeDelete();
        }

        public override bool OnDuringSave()
        {
            foreach (DataRow drw in dbManager.GetDataTable("CL_SalesDetail").Rows)
            {
                switch(drw.RowState)
                {
                    case DataRowState.Deleted:
                        DoRowDeleted(drw);
                        break;
                    case DataRowState.Added:
                        DoRowAdded(drw);
                        break;
                    case DataRowState.Modified:
                        DoRowModified(drw);
                        break;
                }
            }
            return base.OnDuringSave();
        }

        protected void DoRowModified(DataRow drw)
        {
            int idOldItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Original);
            int idNewItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Current);

            if (idOldItem != idNewItem)
            {
                DoRowDeleted(drw);
                DoRowAdded(drw);
            }
        }

        //protected override IRadarParameters GetKeyFromDocument()
        //{
        //    //return new RadarJETemplatesParam(txtTemplate.Text);
        //}

        private bool SalesInvoice_OnEnableToolbarSplitButtons(ToolStripSplitButton sender)
        {
            return true;
        }

        protected override void OnAddSplitMenuButton()
        {

        }

        protected override void OnBindData()
        {
            BindControl(fncInvoiceNo, CL_Sales.DocumentNo, NullValue.NotSet);
            BindControl(ctbDate, CL_Sales.ReleaseDate);
            BindControl(rdrCustomer, CL_Sales.CustID);
            BindControl(txtDescription, CL_Sales.Description);
            BindControl(txtAddress, CL_Sales.Address);
            BindControl(txtCity, CL_Sales.City);
            BindControl(txtCounty, CL_Sales.County);
            BindControl(txtZipCode, CL_Sales.ZipCode);
            BindControl(mtbFiscalCode, CL_Sales.FiscalCode);
            BindControl(ckbPrinted, CL_Sales.Printed, "DBChecked");

            BindCounter(fncInvoiceNo);

            dgwSaleDocDetail.AutoGenerateColumns = false;
            dgwSaleDocDetail.DataSource = dbManager.SlaveBinding("CL_SalesDetail");

            BindColumn(inv_Line, CL_SalesDetail.Line);
            BindColumn(inv_Item, CL_SalesDetail.ItemID);
            BindColumn(inv_Price, CL_SalesDetail.Price);

            BindColumn(inv_Description, CL_SalesDetail.Description);

            inv_Item.DescriptionColumn = CL_SalesDetail.Description;

            dgwSaleDocDetail.AddColumnValidator(CL_SalesDetail.ItemID, new ExtendedDataGridView.DataGridViewColumnValidatingEventHandler(dgwSaleDocDetail_ItemValidating));
            dgwSaleDocDetail.AddColumnChangeValue(CL_SalesDetail.ItemID, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwSaleDocDetail_ItemChange));
            dgwSaleDocDetail.AddColumnChangeValue(CL_SalesDetail.Price, new ExtendedDataGridView.DataGridViewValueChangeEventHandler(dgwSaleDocDetail_Price));
            //dgwJETemplate.DataGridViewRowEnter += new DataGridViewCellEventHandler(dgwJournalEntries_DataGridViewRowEnter);

            dgwSaleDocDetail.AddReadOnlyColumn(CL_SalesDetail.Description, true);
            dgwSaleDocDetail.RowIndex = CL_SalesDetail.Line;
            BindControl(dgwSaleDocDetail);
            BindControl(ntbTotal);
        }
        protected override void OnCustomButtonClick(ToolStripButton button)
        {
            if (button.Name == BTN_LOAD)
                LoadItemsInDocument();

            base.OnCustomButtonClick(button);
        }

        protected override void OnDisableControlsForNew()
        {
            ctbDate.Today = GlobalInfo.CurrentDate;
            base.OnDisableControlsForNew();
        }

        protected override void OnDisableControlsForEdit()
        {
            rdrCustomer.Enabled = !ckbPrinted.Checked;
            base.OnDisableControlsForEdit();
        }

        protected override bool OnEnableToolbarButtons(ToolStripButton button)
        {
            if (button.Name == BTN_LOAD)
               return dbManager.Count >0 && !ckbPrinted.Checked && DocumentMode==DBMode.Edit;

            return base.OnEnableToolbarButtons(button);
        }

        protected override void OnCustomizeToolbar(ToolStrip toolstrip)
        {
            AddCustomButton(BTN_LOAD, "Load data", Properties.Resources.B_Sales, true);
        }

        protected override void OnPrepareAuxData()
        {
            ntbTotal.Double = 0;
            for (int t = 0; t < dgwSaleDocDetail.RowCount; t++)
            {
                duItem.Find(dgwSaleDocDetail.GetValue<int>(t, CL_SalesDetail.ItemID));
                dgwSaleDocDetail.SetValue<string>(t, CL_SalesDetail.Description, duItem.GetValue<string>(CL_SalesDetail.Description));
                ntbTotal.Double += dgwSaleDocDetail.GetValue<double>(t, CL_SalesDetail.Price);
            }
        }

        private void CalculateTotal()
        {
            ntbTotal.Double = 0;
            for (int t = 0; t < dgwSaleDocDetail.RowCount; t++)
                ntbTotal.Double += dgwSaleDocDetail.GetValue<double>(t, CL_SalesDetail.Price);
        }

        private string dgwSaleDocDetail_ItemValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            string msg = string.Empty;

            CheckItemsStatus(e, out msg);
            return msg;
        }

        public virtual void CheckItemsStatus(DataGridViewCellValidatingEventArgs e, out string msg)
        {
            msg = string.Empty;
            if (!duItem.Find(dgwSaleDocDetail.CurrentValue<int>()))
            {
                MyMessageBox(Properties.Resources.Msg_NotFound, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                e.Cancel = true;
                msg = Properties.Resources.Msg_NotFound;
            }
        }

        private void dgwSaleDocDetail_ItemChange(object sender, DataGridViewCellEventArgs e)
        {
            bool bfound = duItem.Find(dgwSaleDocDetail.CurrentValue<int>());
            dgwSaleDocDetail.SetValue<double>(e.RowIndex, CL_SalesDetail.Price, duItem.GetValue<double>(CL_Items.QuotePrice));
        }

        private void dgwSaleDocDetail_Price(object sender, DataGridViewCellEventArgs e)
        {
            CalculateTotal();
        }

        private void rdrCustomer_Validated(object sender, System.EventArgs e)
        {
            int oldCust = dbManager.GetColumn<int>(CL_Sales.CustID, 0, DataRowVersion.Original);
            if (oldCust != rdrCustomer.Text.Int() && oldCust != 0)
            {
                if (MyMessageBox(Properties.Resources.MsgChangeCustomer, Properties.Resources.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.OK)
                    dgwSaleDocDetail.Clear();
                else
                    rdrCustomer.Text = oldCust.ToString();
            }

            bool bFound = drMasters.Find(int.Parse(rdrCustomer.Text));
            txtAddress.Text = drMasters.GetValue<string>(CL_Masters.Address);
            txtZipCode.Text = drMasters.GetValue<string>(CL_Masters.ZipCode);
            txtCity.Text = drMasters.GetValue<string>(CL_Masters.City);
            txtCounty.Text = drMasters.GetValue<string>(CL_Masters.County);
            mtbFiscalCode.Text = drMasters.GetValue<string>(CL_Masters.FiscalCode);
        }

        protected void pf_LoadAddress(ApplicationLibrary.Emailer.emailAddress ea)
        {
            //Plumber.Masters.Library.EmailAddressLoader emailLoader = new Masters.Library.EmailAddressLoader();
            //emailLoader.LoadAddress(ea);
        }

        protected void pf_SendEmail(object sender, EmailArgs e)
        {
            printerForm pf = (printerForm)sender;
            //pf.ChangeParameterValue("HideLogo", false);
            //e.Attachment = pf.ExportToPdf(fncSalesNo.Text);
            //e.Address = GetAddress();
            //e.Subject = string.Format(Properties.Resources.Msg_EmittedInvoice, formatter.ToString(true), ctbDate.Today.ToShortDateString());
        }

        private void ckbPrinted_CheckedChanged(object sender, EventArgs e)
        {
            if (DocumentMode == DBMode.Browse)
                return;

            rdrCustomer.Enabled = !ckbPrinted.Checked;
            ManageOperationButton();
        }
    }

    public class dbmanagerSale : DBManager
    {
        public dbmanagerSale(string name, RadarForm radar, DocumentForm document)
            : base(name, radar, document)
        {
            ForeignKey = CL_Sales.DocumentNo;
        }

        public SalesType SalesType { get; set; }

        protected override SqlABCommand CreateMasterCommand(ref List<SqlABParameter> dParam)
        {
            return base.CreateMasterCommand(ref dParam);
        }

        protected override List<SqlABParameter> CreateMasterParam()
        {
            List<SqlABParameter> PList = new List<SqlABParameter>();

            SqlABParameter sP1 = new SqlABParameter("@p1", CL_Sales.SaledocType);
            sP1.Value = CL_Sales.SaledocType.DefaultValue;
            PList.Add(sP1);

            SqlABParameter sP2 = new SqlABParameter("@p2", CL_Sales.DocumentNo);
            sP2.Value = CL_Sales.DocumentNo.DefaultValue;
            PList.Add(sP2);
            return PList;
        }

        protected override string CreateMasterQuery()
        {
            this.Table = new CL_Sales();
            QueryBuilder qB = new QueryBuilder();
            qB.AddSelect();
            qB.AddFrom(this.Table);
            qB.AddCompare(CL_Sales.SaledocType, "@p1");
            qB.AddCompare(CL_Sales.DocumentNo, "@p2");

            return qB.Query;
        }

        protected override List<SqlABParameter> CreateSlaveParam(string name)
        {
            if (name == CL_SalesDetail.Name)
            {
                List<SqlABParameter> PList = new List<SqlABParameter>();

                SqlABParameter sP1 = new SqlABParameter("@p1", CL_SalesDetail.SaledocType);
                sP1.Value = CL_SalesDetail.SaledocType.DefaultValue;
                PList.Add(sP1);

                SqlABParameter sP2 = new SqlABParameter("@p2", CL_SalesDetail.DocumentNo);
                sP2.Value = CL_SalesDetail.DocumentNo.DefaultValue;
                PList.Add(sP2);
                return PList;
            }
            return null;
        }

        protected override string CreateSlaveQuery(string name)
        {
            if (name == CL_SalesDetail.Name)
            {
                QueryBuilder qB = new QueryBuilder();
                qB.AddSelect();
                qB.AddFrom(CL_SalesDetail.Name);
                qB.AddCompare(CL_SalesDetail.SaledocType, "@p1");
                qB.AddCompare(CL_SalesDetail.DocumentNo, "@p2");
                qB.AddOrder(CL_SalesDetail.Line);
                return qB.Query;
            }
            return "";
        }

        protected override void dAdapter_MasterRowUpdating(object sender, SqlABRowUpdatingEventArgs e)
        {
            if (e.StatementType == StatementType.Insert)
                e.Row[CL_Sales.SaledocType.Name] = SalesType.Int();
            base.dAdapter_MasterRowUpdating(sender, e);
        }

        protected override void dAdapter_RowUpdating(object sender, SqlABRowUpdatingEventArgs e)
        {
            if (e.StatementType == StatementType.Insert)
            {
                if (e.Row.Table.ToString() == CL_SalesDetail.Name)
                {
                    e.Row[CL_SalesDetail.SaledocType.Name] = SalesType.Int();
                    e.Row[CL_SalesDetail.DocumentNo.Name] = GetColumn<string>(CL_Sales.DocumentNo, Pos);
                }
            }
            base.dAdapter_RowUpdating(sender, e);
        }
        protected override void SetParameters(IRadarParameters key, DBCollection collection)
        {
            collection.Parameter[0].Value = SalesType.Int();
            collection.Parameter[1].Value = key[1];
        }
    }

    #region ReturnToCustomer
    public class ReturnToCustomerDoc : SaleDoc
    {
        public ReturnToCustomerDoc()
            : base(SalesType.ReturnToCustomer, Properties.Resources.FN_ReturnToCustomer)
        { }

        protected override void OnAttachData()
        {
            base.OnAttachData();
            FncInvoiceNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_ReturnToCustomer), GlobalInfo.CurrentDate, dbManager.Transaction);
        }

        protected override bool LoadItemsInDocument()
        {
            ReturnToCustomerFilter bolFilter = new ReturnToCustomerFilter(rdrCustomer.CounterNumericValue);
            AddCurrentRows(bolFilter);
            if (bolFilter.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                foreach (ListViewItem lvi in bolFilter.lsvItems.Items)
                {
                    if (lvi.Checked)
                    {
                        DataRowView drw = dgwSaleDocDetail.AddNewRow(CL_SalesDetail.Line);
                        DataRowViewValues.SetValue<int>(drw, CL_SalesDetail.ItemID, int.Parse(lvi.Text));
                        DataRowViewValues.SetValue<string>(drw, CL_SalesDetail.Description, lvi.SubItems[CL_Items.Description.Name].Text);
                        DataRowViewValues.SetValue<double>(drw, CL_SalesDetail.Price, double.Parse(lvi.SubItems[CL_Items.Price.Name].Tag.ToString()));
                    }
                }
            }

            return true;
        }

        protected override void LoadRow(SqlABDataReader dr)
        {
            DataRowView drw = dgwSaleDocDetail.AddNewRow(CL_SalesDetail.Line);
            DataRowViewValues.SetValue<int>(drw, CL_SalesDetail.ItemID, dr.GetValue<int>(CL_Items.ID));
            DataRowViewValues.SetValue<string>(drw, CL_SalesDetail.Description, dr.GetValue<string>(CL_Items.Description));
            DataRowViewValues.SetValue<double>(drw, CL_SalesDetail.Price, dr.GetValue<double>(CL_Items.Price));
        }

        public override void CheckItemsStatus(DataGridViewCellValidatingEventArgs e, out string msg)
        {
            base.CheckItemsStatus(e, out msg);
            if (e.Cancel == true)
                return;

            ItemStatus itemStatus = duItem.GetValue<ItemStatus>(CL_Items.Status);
            if (itemStatus != ItemStatus.E_Load)
            {
                switch (itemStatus)
                {
                    case ItemStatus.E_Sold:
                        MyMessageBox(Properties.Resources.Msg_ItemAlreadySold, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        e.Cancel = true;
                        msg = Properties.Resources.Msg_ItemAlreadySold;
                        break;
                    case ItemStatus.E_Return:
                    case ItemStatus.E_Beneficence:
                        if (duItem.GetValue<string>(CL_Items.ReturnToCustomerNo) != fncInvoiceNo.Text)
                        {
                            msg = string.Format(Properties.Resources.Msg_ItemAlreadyReturned, duItem.GetValue<string>(CL_Items.ReturnToCustomerNo));
                            MyMessageBox(msg, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            e.Cancel = true;
                        }
                        break;
                }
            }
        }

        private void AddCurrentRows(ReturnToCustomerFilter bolFilter)
        {
            bolFilter.ItemsID.Clear();

            for (int t = 0; t < dgwSaleDocDetail.RowCount; t++)
                bolFilter.ItemsID.Add(dgwSaleDocDetail.GetValue<int>(t, CL_SalesDetail.ItemID));
        }

        protected override void DoRowDeleted(DataRow drw)
        {
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Original);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.ReturnToCustomer, false);
                duItem.SetValue<string>(CL_Items.ReturnToCustomerNo, "");
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Load.Int());
                duItem.Update();
            }
        }

        protected override void DoRowAdded(DataRow drw)
        {
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Current);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.ReturnToCustomer, true);
                duItem.SetValue<string>(CL_Items.ReturnToCustomerNo, FncInvoiceNo.Text);
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Return.Int());
                duItem.Update();
            }
        }
    } 
    #endregion

    #region BillOfLading
    public class BillOfLadingDoc : SaleDoc
    {
        public BillOfLadingDoc()
            : base(SalesType.DeliveryNote, Properties.Resources.FN_BillOfLading)
        { }

        protected override void OnAttachData()
        {
            base.OnAttachData();
            FncInvoiceNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_BillOfLading), GlobalInfo.CurrentDate, dbManager.Transaction);
        }

        protected override bool LoadItemsInDocument()
        {
            QueryBuilder qb = new QueryBuilder();
            using (SqlABCommand scc = new SqlABCommand(GlobalInfo.LoginInfo.ProviderType))
            {
                scc.Connection = GlobalInfo.SqlConnection;

                qb.AddSelect();
                qb.AddFrom(CL_Items.Name);

                SqlABParameter sqlP1 = null, sqlP3 = null;
                sqlP1 = new SqlABParameter("@p1", CL_Items.BillOfLading);
                sqlP3 = new SqlABParameter("@p3", CL_Items.Status);
                sqlP3.Value = ItemStatus.E_Null;
                qb.AddCompare(CL_Items.Status, sqlP3);

                sqlP1.Value = false;
                qb.AddCompare(CL_Items.Invoice, sqlP1);

                SqlABParameter sqlP2 = new SqlABParameter("@p2", CL_Items.Customer);
                sqlP2.Value = rdrCustomer.CounterNumericValue;
                qb.AddCompare(CL_Items.Customer, sqlP2);

                scc.Parameters.Add(sqlP1);
                scc.Parameters.Add(sqlP2);
                scc.Parameters.Add(sqlP3);

                scc.CommandText = qb.Query;

                SqlABDataReader dr = scc.ExecuteReader();
                if (dr.HasRows)
                    dgwSaleDocDetail.DeleteEmptyRows();

                try
                {
                    while (dr.Read())
                        LoadRow(dr);
                }
                catch (System.Exception e)
                {
                    if (ApplicationLibrary.Emailer.EmailSender.SendException)
                    {
                        ApplicationLibrary.Emailer.EmailSender.ToAddress = "mauro.rogledi@gmail.com";
                        ApplicationLibrary.Emailer.EmailSender.SendMail(e.Message, e.StackTrace, "");
                    }
                }
                finally
                {
                    dr.Close();
                }
            }
            return true;
        }

        protected override void LoadRow(SqlABDataReader dr)
        {
            DataRowView drw = dgwSaleDocDetail.AddNewRow(CL_SalesDetail.Line);
            DataRowViewValues.SetValue<int>(drw, CL_SalesDetail.ItemID, dr.GetValue<int>(CL_Items.ID));
            DataRowViewValues.SetValue<string>(drw, CL_SalesDetail.Description, dr.GetValue<string>(CL_Items.Description));
            DataRowViewValues.SetValue<double>(drw, CL_SalesDetail.Price, dr.GetValue<double>(CL_Items.Price));
        }

        public override void CheckItemsStatus(DataGridViewCellValidatingEventArgs e, out string msg)
        {
            base.CheckItemsStatus(e, out msg);
            if (e.Cancel == true)
                return;

            ItemStatus itemStatus = duItem.GetValue<ItemStatus>(CL_Items.Status);
            if (itemStatus != ItemStatus.E_Load)
            {
                switch (itemStatus)
                {
                    case ItemStatus.E_Sold:
                        MyMessageBox(Properties.Resources.Msg_ItemAlreadySold, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        e.Cancel = true;
                        msg = Properties.Resources.Msg_ItemAlreadySold;
                        break;
                    case ItemStatus.E_Return:
                        if (duItem.GetValue<string>(CL_Items.ReturnToCustomerNo) != fncInvoiceNo.Text)
                        {
                            msg = string.Format(Properties.Resources.Msg_ItemAlreadyReturned, duItem.GetValue<string>(CL_Items.ReturnToCustomerNo));
                            MyMessageBox(msg, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            e.Cancel = true;
                        }
                        break;
                    case ItemStatus.E_Beneficence:
                            msg = string.Format(Properties.Resources.Msg_ItemAlreadyReturned, duItem.GetValue<string>(CL_Items.ReturnToCustomerNo));
                            MyMessageBox(msg, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            e.Cancel = true;
                        break;
                }
            }

        }

        protected override void DoRowDeleted(DataRow drw)
        {
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Original);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.BillOfLading, false);
                duItem.SetValue<string>(CL_Items.BillOfLadingNo, "");
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Null.Int());
                duItem.Update();
            }
        }

        protected override void DoRowAdded(DataRow drw)
        {
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Current);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.BillOfLading, true);
                duItem.SetValue<string>(CL_Items.BillOfLadingNo, FncInvoiceNo.Text);
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Load.Int());
                duItem.Update();
            }
        }
    } 
    #endregion

    #region Invoice
    public class InvoiceDoc : SaleDoc
    {
        public InvoiceDoc()
            : base(SalesType.Invoice, Properties.Resources.FN_Invoice)
        { }

        protected override void OnAddSplitMenuButton()
        {
            AddSplitPreviewButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPreviewButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Letter, Properties.Resources.B_Envelope);

            AddSplitPrintButton(Properties.Resources.PRNT_INVOICE, PRINT_INVOICE, PrintType.Letter, Properties.Resources.B_Invoice);
            AddSplitPrintButton(Properties.Resources.PRNT_ENVELOPE, PRINT_ENVELOPE, PrintType.Envelope, Properties.Resources.B_Envelope);
        }

        protected override void OnAttachData()
        {
            base.OnAttachData();
            FncInvoiceNo.AttachCounterType(GlobalInfo.GetCounter(Properties.Resources.CN_Invoice), GlobalInfo.CurrentDate, dbManager.Transaction);
        }

        protected override bool LoadItemsInDocument()
        {
            QueryBuilder qb = new QueryBuilder();
            using (SqlABCommand scc = new SqlABCommand(GlobalInfo.LoginInfo.ProviderType))
            {
                scc.Connection = GlobalInfo.SqlConnection;

                qb.AddSelect();
                qb.AddFrom(CL_Items.Name);

                SqlABParameter sqlP1 = null, sqlP3 = null;
                sqlP1 = new SqlABParameter("@p1", CL_Items.Invoice);
                sqlP3 = new SqlABParameter("@p3", CL_Items.Status);
                sqlP3.Value = ItemStatus.E_Sold.Int();
                qb.AddCompare(CL_Items.Status, sqlP3);

                sqlP1.Value = false;
                qb.AddCompare(CL_Items.Invoice, sqlP1);

                SqlABParameter sqlP2 = new SqlABParameter("@p2", CL_Items.Customer);
                sqlP2.Value = rdrCustomer.CounterNumericValue;
                qb.AddCompare(CL_Items.Customer, sqlP2);

                scc.Parameters.Add(sqlP1);
                scc.Parameters.Add(sqlP2);
                scc.Parameters.Add(sqlP3);
                scc.CommandText = qb.Query;

                SqlABDataReader dr = scc.ExecuteReader();
                if (dr.HasRows)
                    dgwSaleDocDetail.DeleteEmptyRows();

                try
                {
                    while (dr.Read())
                        LoadRow(dr);
                }
                catch (System.Exception e)
                {
                    if (ApplicationLibrary.Emailer.EmailSender.SendException)
                    {
                        ApplicationLibrary.Emailer.EmailSender.ToAddress = "mauro.rogledi@gmail.com";
                        ApplicationLibrary.Emailer.EmailSender.SendMail(e.Message, e.StackTrace, "");
                    }
                }
                finally
                {
                    dr.Close();
                }
            }
            return true;
        }

        protected override void LoadRow(SqlABDataReader dr)
        {
            DataRowView drw = dgwSaleDocDetail.AddNewRow(CL_SalesDetail.Line);
            DataRowViewValues.SetValue<int>(drw, CL_SalesDetail.ItemID, dr.GetValue<int>(CL_Items.ID));
            DataRowViewValues.SetValue<string>(drw, CL_SalesDetail.Description, dr.GetValue<string>(CL_Items.Description));
            DataRowViewValues.SetValue<double>(drw, CL_SalesDetail.Price, dr.GetValue<double>(CL_Items.PriceSale)/ 2) ;
        }

        public override void CheckItemsStatus(DataGridViewCellValidatingEventArgs e, out string msg)
        {
            base.CheckItemsStatus(e, out msg);
            if (e.Cancel == true)
                return;

            ItemStatus itemStatus = duItem.GetValue<ItemStatus>(CL_Items.Status);
            if (itemStatus != ItemStatus.E_Load)
            {
                switch (itemStatus)
                {
                    case ItemStatus.E_Sold:
                        if (duItem.GetValue<string>(CL_Items.InvoiceNo) != fncInvoiceNo.Text)
                        {
                            msg = string.Format(Properties.Resources.Msg_ItemAlreadyInvoiced, duItem.GetValue<string>(CL_Items.InvoiceNo));
                            MyMessageBox(msg, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            e.Cancel = true;
                        }
                        break;
                    case ItemStatus.E_Return:
                    case ItemStatus.E_Beneficence:
                        msg = string.Format(Properties.Resources.Msg_ItemAlreadyReturned, duItem.GetValue<string>(CL_Items.ReturnToCustomerNo));
                        MyMessageBox(msg, Properties.Resources.Warning, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        e.Cancel = true;
                        break;
                }
            }
        }

        protected override void DoRowDeleted(DataRow drw)
        {
            DateTime empty = new DateTime();
            empty.EmptyDate();
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Original);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.Invoice, false);
                duItem.SetValue<string>(CL_Items.InvoiceNo, "");
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Load.Int());
                duItem.SetValue<double>(CL_Items.PriceSale, 0);
                duItem.SetValue<DateTime>(CL_Items.SoldDate,empty.EmptyDate());
                duItem.Update();
            }
        }

        protected override void DoRowAdded(DataRow drw)
        {
            int idItem = DataRowValues.GetValue<int>(drw, CL_SalesDetail.ItemID, DataRowVersion.Current);
            double priceSale = DataRowValues.GetValue<int>(drw, CL_SalesDetail.Price, DataRowVersion.Current);
            if (duItem.Find(idItem))
            {
                duItem.SetValue<bool>(CL_Items.Invoice, true);
                duItem.SetValue<string>(CL_Items.InvoiceNo, FncInvoiceNo.Text);
                duItem.SetValue<int>(CL_Items.Status, ItemStatus.E_Sold.Int());
                duItem.SetValue<double>(CL_Items.PriceSale, priceSale);
                duItem.Update();
            }
        }

        protected override bool OnPrintDocument(PrintInfo sender, printerForm pf)
        {
            pf.SendEmail += new printerForm.EmailArgsEventHanlder(pf_SendEmail);
            pf.LoadAddress += new printerForm.LoadAddressEventHandler(pf_LoadAddress);
            switch (sender.ReportName)
            {
                case PRINT_INVOICE:
                    return PrintInvoice(pf, true);
                case PRINT_ENVELOPE:
                    return PrintEnvelope(pf);
                default:
                    return true;
            }
        }

        private bool PrintInvoice(printerForm pf, bool hidelogo = true)
        {
            DSInvoice dsInvoice = new DSInvoice();
            DSInvoice.HeaderRow headerRow = dsInvoice.Header.NewHeaderRow();

            pf.Text = Properties.Resources.PRNT_INVOICE;

            //pf.Text = Properties.Resources.PRNT_INVOICE;
            string trimmedDesc = txtDescription.Text.TrimEnd(new Char[] { '\r', '\n', '\t', ' ' });

            //formatter.Text = fncSalesNo.Text;
            headerRow.DocumentNo = fncInvoiceNo.Text;
            string desc = txtDescription.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' });
            desc = desc.SeparConcat(txtAddress.Text.TrimAll(new Char[] { '\r', '\n', '\t', ' ' }), "\n");

            headerRow.Description = string.Concat(desc, "\n", txtZipCode.Text, " ", txtCity.Text, " ", txtCounty.Text);
            headerRow.ReleaseDate = ctbDate.Today;
            headerRow.CustID = rdrCustomer.CounterNumericValue;
            // headerRow.FiscalCode = mtbFiscalCode.Text;


            dsInvoice.Header.AddHeaderRow(headerRow);
            //pf.SetParameterValue("HideLogo", hidelogo);
            //if (ckbRestraint.Checked)
            //    pf.SetParameterValue("TotalDesc", "TOTALE-RITENUTA");
            //else if (ckbDeduction.Checked)
            //    pf.SetParameterValue("TotalDesc", "TOTALE-DETRAZIONE");
            //else
            //    pf.SetParameterValue("TotalDesc", "");

            for (int t = 0; t < dgwSaleDocDetail.RowCount; t++)
            {
                DSInvoice.RowRow rowRow = dsInvoice.Row.NewRowRow();
                rowRow.DocumentNo = fncInvoiceNo.Text;
                rowRow.ItemID = dgwSaleDocDetail.GetValue<int>(t, CL_SalesDetail.ItemID);
                rowRow.Description = dgwSaleDocDetail.GetValue<string>(t, CL_SalesDetail.Description);
                rowRow.Price = dgwSaleDocDetail.GetValue<double>(t, CL_SalesDetail.Price);

                dsInvoice.Row.AddRowRow(rowRow);
            }

            pf.ShowReport(new RPTInvoice(), dsInvoice);
            return true;
        }

        private bool PrintEnvelope(printerForm pf)
        {
            //Plumber.Masters.Library.PrintEnvelope printEnvelope = new Plumber.Masters.Library.PrintEnvelope(pf);

            //if (masterType == MasterTypes.E_Condominium && !string.IsNullOrEmpty(rdrAdmin.Text))
            //{
            //    if (DRMaster.Find(adminType, rdrAdmin.Text))
            //    {
            //        string titleText = "";
            //        if (DRTitle.Find(DRMaster.GetValue<string>(PL_Masters.Title)))
            //            titleText = DRTitle.GetValue<string>(PL_Titles.Description);

            //        printEnvelope.Print(titleText,
            //                            DRMaster.GetValue<string>(PL_Masters.Description),
            //                            DRMaster.GetValue<string>(PL_Masters.Address),
            //                            DRMaster.GetValue<string>(PL_Masters.ZipCode),
            //                            DRMaster.GetValue<string>(PL_Masters.City),
            //                            DRMaster.GetValue<string>(PL_Masters.County));
            //    }
            //}
            //else
            //    printEnvelope.Print(lblTitleDesc.Text, txtDescription.Text, txtAddress.Text, mtbZip.Text, txtCity.Text, txtCounty.Text);

            return true;
        }

    } 
    #endregion
}